home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-02-21 | 4.9 KB | 124 lines | [TEXT/CCL2] |
- (in-package :cl-user)
- (require :closstar)
- (use-package :clos*)
-
- ;;; Pixmap tools
-
- ;;; better hook to inspector
- ;;; deal with non-zero-based pixmaps, ridiculous sizes, etc.
- ;;; deallocate on window close (not for inspect, but as an option for other views)
-
- (defclass pm-inspect-window (window) ((pixmap :initarg :pixmap)))
-
- (defmethod view-draw-contents ((w pm-inspect-window))
- (with-slots (wptr pixmap) w
- (with-port wptr
- (ccl:with-pointers ((source pixmap)
- (dest (ccl:rref wptr window.portbits)))
- (let ((bounds (rref source pixmap.bounds :storage :pointer)))
- (#_CopyBits source dest
- bounds bounds 0 (%null-ptr)))))))
-
- (defun inspect-pm (pm)
- (let* ((w (rref pm pixmap.bounds.right))
- (h (rref pm pixmap.bounds.bottom)))
- (make-instance 'pm-inspect-window
- :pixmap pm :view-size (make-point w h) :window-title (princ-to-string pm))))
-
- (defclass* pixmap-dialog-item (dialog-item)
- (pixmap
- (dispose nil)) ; GWorld, or T to dispose of pixmap, or NIL
- :initable-instance-variables)
-
- (defmethod* initialize-instance :after ((pmdi pixmap-dialog-item) &rest ignore)
- (when pixmap
- (set-view-size pmdi (make-point (rref pixmap pixmap.bounds.right)
- (rref pixmap pixmap.bounds.bottom)))))
-
- (defmethod* view-default-size ((pmdi pixmap-dialog-item))
- (when pixmap
- (make-point (rref pixmap pixmap.bounds.right)
- (rref pixmap pixmap.bounds.bottom))))
-
- (defmethod* view-draw-contents ((pmdi pixmap-dialog-item))
- (with-port wptr
- (ccl:with-pointers ((source pixmap)
- (dest (ccl:rref wptr window.portbits)))
- (let ((source-rect (rref source pixmap.bounds :storage :pointer))
- (x (point-h view-position))
- (y (point-v view-position)))
- (rlet ((dest-rect rect
- :top y :left x
- :bottom (+ y (point-v view-size))
- :right (+ x (point-h view-size))))
- (#_CopyBits source dest
- source-rect
- dest-rect
- 0 (ccl::%null-ptr)))))))
-
- ;;; This presumes the pixmap is a screen buffer, and isn't in use somewhere else.
- (defmethod* remove-view-from-window ((pmdi pixmap-dialog-item))
- (cond ((eq dispose t)
- (#_disposescreenbuffer pixmap)) ; will this work on other pixmaps? Who knows?
- (dispose ; non-nil non-t means it's a gworld
- (#_DisposeGWorld dispose)))
- (call-next-method))
-
- ;;; Body should consist of low-level Quickdraw calls, which will be performed on the generated bitmap.
- ;;; Bugs: doesn't deallocate gworld (because doing so flushes the pixmap as well)
- ;;; Temporary fix: return gworld as second value so higher level can dispose of it someday.
- (defmacro make-pixmap ((w h) &body body)
- `(rlet ((cgrafptr :pointer) (gdhandle :pointer))
- (#_GetGWorld cgrafptr gdhandle)
- (let* ((gworld (make-gworld ,w ,h))
- (pixmap (#_GetGWorldPixMap gworld)))
- (unwind-protect
- (progn
- (#_SetGworld gworld (ccl:%null-ptr))
- (#_LockPixels pixmap)
- (#_EraseRect (ccl:rref gworld cgrafport.portrect))
- ,@body))
- (#_UnLockPixels pixmap)
- (#_SetGWorld (ccl:%get-ptr cgrafptr) (ccl:%get-ptr gdhandle))
- (values pixmap gworld))))
-
- (defun make-gworld (w h)
- (rlet ((bounds-rect :rect :top 0 :left 0 :right w :bottom h)
- (gworldp :pointer))
- (unless (zerop (#_NewGWorld gworldp 0 bounds-rect (ccl:%null-ptr) (ccl:%null-ptr) 0))
- (error "Failed to make gworld"))
- (ccl:%get-ptr gworldp)))
-
- (require :pict-scrap)
-
- (defmethod picture-to-window
- ((self window) picture &optional left top right bottom)
- (when picture
- (with-focused-view self
- (with-port (wptr self)
- (cond ((null left)
- (with-pointers ((pict-point picture))
- (#_DrawPicture picture (rref pict-point picture.picframe :storage :pointer))))
- ((rlet ((r :rect :left left :top top :right right :bottom bottom))
- (#_DrawPicture picture r))))))))
-
- (defun window-snapshot (window &optional box (scale 1) frame)
- (let* ((wptr (slot-value window 'wptr))
- (source-rect (or box (rref wptr window.portrect)))
- (w-width (- (rref source-rect rect.right)
- (rref source-rect rect.left)))
- (w-height (- (rref source-rect rect.bottom)
- (rref source-rect rect.top))))
- (make-pixmap ((round (* w-width scale))
- (round (* w-height scale)))
- (with-pointers ((source (rref wptr window.portbits))
- (dest (rref (ccl::%getport) window.portbits)))
- (#_CopyBits source
- dest
- source-rect
- (rref (ccl::%getport) window.portrect)
- 0 (%null-ptr))
- (when frame
- (#_FrameRect (rref (ccl::%getport) window.portrect)))))))
-
-